package com.pingancar.creditmanage.dao;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * Created by liymm on 2014-12-31.
 */
abstract public class BaseDAO<T> {

   /**
     * 当前T的对象
     */
    protected Class<T> persistentClass;

    public BaseDAO() {
        Type type = getClass().getGenericSuperclass();
        Type[] trueType = ((ParameterizedType) type).getActualTypeArguments();
        this.persistentClass = (Class<T>) trueType[0];
    }

    /**
     * Autowired 自动装配 相当于get() set()
     */
    @Autowired
    protected SessionFactory sessionFactory;

    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    /**
     * openSession 需要手动关闭session 意思是打开一个新的session
     *
     * @return
     */
    public Session getNewSession() {
        return sessionFactory.openSession();
    }

    public void flush() {
        getSession().flush();
    }

    public void clear() {
        getSession().clear();
    }

    /**
     * 根据 id 查询信息
     *
     * @param id
     * @return
     */
    @SuppressWarnings("rawtypes")
    public T load(Integer id) {
        Session session = getSession();
        return (T)session.get(persistentClass, id);
    }

    /**
     * 获取所有信息
     *
     * @return
     */
    @SuppressWarnings({ "rawtypes" })
    public List getAllList() {
        String hql = "from " + persistentClass.getName();
        Session session = getSession();
        return session.createQuery(hql).list();
    }

    /**
     * 获取总数量
     *
     * @return
     */
    public Long getTotalCount() {
        Session session = getSession();
        String hql = "select count(*) from " + persistentClass.getName();
        Long count = (Long) session.createQuery(hql).uniqueResult();
        return count != null ? count.longValue() : 0;
    }

    /**
     * 保存
     *
     * @param bean
     *
     */
    public Serializable save(T bean) {
        try {
            Session session = getSession();
            Serializable s = session.save(bean);
            session.flush();
            session.clear();
            return s;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 更新
     *
     * @param bean
     *
     */
    public void update(T bean) {
        Session session = getSession();
        session.update(bean);
        session.flush();
        session.clear();
    }

    /**
     * 删除
     *
     * @param bean
     *
     */
    public void delete(T bean) {
        Session session = getSession();
        session.delete(bean);
        session.flush();
        session.clear();
    }

    /**
     * 根据ID删除
     *
     * @param id ID
     *
     */
    @SuppressWarnings({ "rawtypes" })
    public void delete(Integer id) {
        Session session = getSession();
        Object obj = session.get(persistentClass, id);
        session.delete(obj);
        session.flush();
        session.clear();
    }

    /**
     * 批量删除
     *
     * @param ids ID 集合
     */
    @SuppressWarnings({ "rawtypes" })
    public void delete(Integer[] ids) {
        for (Integer id : ids) {
            Object obj = getSession().get(persistentClass, id);
            if (obj != null) {
                getSession().delete(obj);
            }
        }
    }

    public static final int ASC = 0;
    public static final int DESC = 1;


    protected String getOrderHQL(String property, Integer order) {
        StringBuilder orderHQL = new StringBuilder();
        orderHQL.append(" order by ").append(property);
        if (order == ASC)
            orderHQL.append(" asc");
        else
            orderHQL.append(" desc");

        return orderHQL.toString();
    }

    public List<T> findByProperty(String name, Object value) {
        Session session = getSession();
        String hql = "from " + persistentClass.getName() + " temp where temp." + name +  " = :val";
        Query q = session.createQuery(hql);
        q.setParameter("val", value);
        return q.list();
    }
}
